package com.example.onlinemonitoring.comCenter;

import com.example.onlinemonitoring.Util.CRC16;
import com.example.onlinemonitoring.Util.CommPortManager;
import com.example.onlinemonitoring.Util.HexUtil;
import com.example.onlinemonitoring.model.Dqjdcwsensor;
import com.example.onlinemonitoring.model.O2andsf6sensor;
import com.example.onlinemonitoring.model.common.MyResult;
import com.example.onlinemonitoring.model.Dqjdcwhistory;
import com.example.onlinemonitoring.model.Appdevice;
import com.example.onlinemonitoring.model.Byqpdsensor;
import com.example.onlinemonitoring.serviceImpl.DqjdcwsensorServiceImpl;

import org.apache.commons.math3.distribution.TDistribution;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.context.annotation.Scope;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/*这里beanName需要和数据库Appdevice中的simple对应并加上Com,不对应请自行修改
    例:simple:dlhl
    @Service("dlhlCom")
*/
@Service("dqjdcwCom")
@Scope("prototype")
public class DqjdcwCom extends CommPortManager {
        @Autowired
        private DqjdcwsensorServiceImpl dqjdcwsensorServiceImpl;
        int Pointcount = 0;
        @Override
        public void receiveData(String str) {
            try {
                str = str.toUpperCase();
                setText(str);
                //条件判断自己写
                String addrstr = str.substring(0, 2);
                Integer addr = parseHex4(addrstr);
    
                if (!"03".equals(str.substring(2, 4)))
                return;
                int ckaddr = 0;
                reSend[addrindex] = 0;
                addrindex++;
                if (str.length()<22)
                return;
                int num = 0;
                float TA =0;
                float TB =0;
                float TC =0;
                int TD =0;
                int Cewenstatus =0;
                float sbv=0;
                int sbcount =0;
                if(ad.getBrand().equals("旧协议"))
                {
                    Dqjdcwsensor dqsensor =  new Dqjdcwsensor();
                    dqsensor.setStationid(ad.getStationid());
                    dqsensor.setDeviceaddr(addr);
                    dqsensor.setDevicegroup(ad.getDevicegroup());
                    MyResult<Dqjdcwsensor> res = dqjdcwsensorServiceImpl.getList(dqsensor);
                    num=res.getCount();
                    for (int i = 0; i < num; i++)
                    {

                        Dqjdcwsensor record = res.getData().get(i);
                        if (record == null) {
                            setText("当前数据库无监测点：设备地址" + addr + "的监测点" + i+1 + " ！ 请先添加该监测点！");
                            return;
                        }


                        if(record.getInuse()==0)
                            continue;

                        //if(ad.getBrand().equals("旧协议"))
                        //{
                            ckaddr = (i * 12);

                            TA = parseHex4(str.substring(ckaddr + 10, ckaddr + 14));
                            TB = parseHex4(str.substring(ckaddr + 14, ckaddr + 18));
                            TC = parseHex4(str.substring(ckaddr + 18, ckaddr + 22));

                            setText("温度A：" + TA/10 + "℃ " + "温度B：" + TB/10 + "℃ "+ "温度C：" + TC/10 + "℃ " );
                            {
                                Cewenstatus =Integer.parseInt(str.substring(6,  8), 16)* 256 + Integer.parseInt(str.substring( 8,  10), 16);
                                int Duanxiang = Cewenstatus & 0x1;
                                int Guzhang = Cewenstatus & 0x2;

                                if(Duanxiang==1)
                                    setText(" 断线" );
                                if(Guzhang==1)
                                    setText(" 故障"  );

                            }

                            setText(" 监测点:" + (i+1)  );

                        //}
                       // else
                        //{
                            // ckaddr = (i * 48);
                            // TA = parseHex4(str.substring(ckaddr + 14, ckaddr + 18));
                            // //TB = parseHex4(str.substring(ckaddr + 18, ckaddr + 22));          
                            // //TC = parseHex4(str.substring(ckaddr + 22, ckaddr + 26));
                            // //TD = parseHex4(str.substring(ckaddr + 26, ckaddr + 30));
                    
                            // sbv=Integer.parseInt(str.substring(ckaddr + 30, ckaddr + 34), 16);
                            // sbcount=Integer.parseInt(str.substring(ckaddr + 34, ckaddr + 38))* 256+ Integer.parseInt(str.substring( ckaddr + 38, ckaddr + 42), 16);;
                            // Cewenstatus = Integer.parseInt(str.substring(ckaddr + 42, ckaddr + 44), 16);

                            // int Duanxiang = Cewenstatus & 0x1;
                            // int Guzhang = Cewenstatus & 0x2;
                            // setText("温度：" + TA/10 + "℃ " );
                            // //setText("温度A：" + TA/10 + "℃ " + "温度B：" + TB/10 + "℃ "+ "温度C：" + TC/10 + "℃ " +"温度D：" + TD/10 + "℃ " );
                            // setText(" 电压：" + sbv);
                            // setText(" 次数：" + sbcount);
                            // if(Duanxiang==1)
                            //     setText(" 断线" );
                            // if(Guzhang==1)
                            //     setText(" 故障"  );

                            // setText(" 监测点:" + (i+1)  );
                        //}
                        // String stlyestr = record.getStyle();
                        // if((stlyestr==null)||(stlyestr.equals("")))
                        // {
                        //     stlyestr="temperature|1|温度,humidity|1|湿度,sf6|1|SF6,o2consistence|1|氧气浓度,";
                        //     o2andsf6sensor.setStyle(stlyestr);
                        // }
                        dqsensor.setPointaddr(record.getPointaddr());
                        dqsensor.setLastatemper(TA/10);
                        dqsensor.setLastbtemper(TB/10);
                        dqsensor.setLastctemper(TC/10);
                       // dqsensor.setLastdtemper((float)TD/10);
                        dqsensor.setLastsbalarmstatus(Cewenstatus);
                        //dqsensor.setLastv(sbv);
                        //dqsensor.setLastcount(sbcount);
                        AddAndUpdate(record,dqsensor);
                    }                
                }
                if(ad.getBrand().equals("新协议"))
                {
                    Dqjdcwsensor ndq = new Dqjdcwsensor();
                    ndq.setStationid(ad.getStationid());
                    ndq.setDevicegroup(ad.getDevicegroup());
                    ndq.setDeviceaddr(addr);
                    ndq.setPointaddr(Pointcount);
                    ndq = dqjdcwsensorServiceImpl.getModel(ndq);

                   // ckaddr = (i * 48);
                    TA = parseHex4(str.substring(ckaddr + 14, ckaddr + 18));
                    //TB = parseHex4(str.substring(ckaddr + 18, ckaddr + 22));          
                    //TC = parseHex4(str.substring(ckaddr + 22, ckaddr + 26));
                    //TD = parseHex4(str.substring(ckaddr + 26, ckaddr + 30));
                
                    sbv=Integer.parseInt(str.substring(ckaddr + 30, ckaddr + 34), 16);
                    sbcount=Integer.parseInt(str.substring(ckaddr + 34, ckaddr + 38))* 256+ Integer.parseInt(str.substring( ckaddr + 38, ckaddr + 42), 16);;
                    Cewenstatus = Integer.parseInt(str.substring(ckaddr + 42, ckaddr + 44), 16);

                    int Duanxiang = Cewenstatus & 0x1;
                    int Guzhang = Cewenstatus & 0x2;
                    setText("温度：" + TA/10 + "℃ " );
                    //setText("温度A：" + TA/10 + "℃ " + "温度B：" + TB/10 + "℃ "+ "温度C：" + TC/10 + "℃ " +"温度D：" + TD/10 + "℃ " );
                    setText(" 电压：" + sbv);
                    setText(" 次数：" + sbcount);
                    if(Duanxiang==1)
                        setText(" 断线" );
                    if(Guzhang==1)
                        setText(" 故障"  );

                    setText(" 监测点:" + Pointcount  );

                    
                    ndq.setLastatemper(TA/10);
                    ndq.setLastbtemper(TB/10);
                    ndq.setLastctemper(TC/10);
                    ndq.setLastdtemper((float)TD/10);
                    ndq.setLastsbalarmstatus(Cewenstatus);
                    ndq.setLastv(sbv);
                    ndq.setLastcount(sbcount);
                    AddAndUpdate(ndq,ndq);
                }

            } catch (Exception ex) {
                ex.printStackTrace();
                setText("从设备返回的数据有误！请检查串口！");
            }
        }

        @Transactional
        private void AddAndUpdate(Dqjdcwsensor record,Dqjdcwsensor dqsensor) {
            int alarmLevel = 0;// 报警等级
            String alarmMessage = "";// 报警消息
            //报警逻辑
            //这里写报警逻辑
            if (

                record.getTemperalarmvalue() == null ||
                record.getTemperalarmrelievevalue() == null ||
                record.getTemperwarnvalue() == null ||
                record.getTemperwarnrelievevalue() == null 
        ) {
            setText("设备地址" + record.getDeviceaddr() + " 未设置报警值！");
            return;
        } 
        List<Integer> array = new ArrayList<>();
        dqsensor.setLastawalarmstatus(
            GetAlarmStatus(isnull(dqsensor.getLastatemper()), isnull(record.getTemperalarmvalue()),
                    isnull(record.getTemperalarmrelievevalue()), isnull(record.getTemperwarnvalue()),
                    isnull(record.getTemperwarnrelievevalue()),
                    isnull(record.getLastawalarmstatus()), true, "A温度", record.getDevicegroup(), record.getDeviceaddr(),
                    record.getPointname(),record.getPointaddr()));
        alarmMessage += GetAlarmMessage(dqsensor.getLastawalarmstatus(), "A温度");
        array.add(isnull(dqsensor.getLastawalarmstatus()));
        dqsensor.setLastbwalarmstatus(
            GetAlarmStatus(isnull(dqsensor.getLastbtemper()), isnull(record.getTemperalarmvalue()),
                    isnull(record.getTemperalarmrelievevalue()), isnull(record.getTemperwarnvalue()),
                    isnull(record.getTemperwarnrelievevalue()),
                    isnull(record.getLastbwalarmstatus()), true, "B温度", record.getDevicegroup(), record.getDeviceaddr(),
                    record.getPointname(),record.getPointaddr()));
        alarmMessage += GetAlarmMessage(dqsensor.getLastbwalarmstatus(), "B温度");
        array.add(isnull(dqsensor.getLastbwalarmstatus()));
        dqsensor.setLastcwalarmstatus(
            GetAlarmStatus(isnull(dqsensor.getLastctemper()), isnull(record.getTemperalarmvalue()),
                    isnull(record.getTemperalarmrelievevalue()), isnull(record.getTemperwarnvalue()),
                    isnull(record.getTemperwarnrelievevalue()),
                    isnull(record.getLastcwalarmstatus()), true, "C温度", record.getDevicegroup(), record.getDeviceaddr(),
                    record.getPointname(),record.getPointaddr()));
        alarmMessage += GetAlarmMessage(dqsensor.getLastcwalarmstatus(), "C温度");
        array.add(isnull(dqsensor.getLastcwalarmstatus()));
        // dqsensor.setLastdwalarmstatus(
        //     GetAlarmStatus(isnull(dqsensor.getLastdtemper()), isnull(record.getTemperalarmvalue()),
        //             isnull(record.getTemperalarmrelievevalue()), isnull(record.getTemperwarnvalue()),
        //             isnull(record.getTemperwarnrelievevalue()),
        //             isnull(dqsensor.getLastdwalarmstatus()), true, "D温度", record.getDevicegroup(), record.getDeviceaddr(),
        //             record.getPointname(),record.getPointaddr()));
        // alarmMessage += GetAlarmMessage(dqsensor.getLastdwalarmstatus(), "D温度");
        // array.add(record.getLastdwalarmstatus());
        alarmLevel = HexUtil.MAX(array);
            dqsensor.setLastalarmlevel(alarmLevel);
            dqsensor.setLastalarmlevel(alarmLevel);
            dqsensor.setLastalarmmessage(alarmMessage);
            dqsensor.setLastcommunicationstatus(0);
            dqsensor.setLastdatatime(new Date());
            dqsensor.setLasthisdatatime(addHistory(record));
            if ( dqjdcwsensorServiceImpl.Update(dqsensor, false) == 0) {
                setText("更新实时数据失败，请检查数据库连接");
            }
        }
        private Date addHistory(Dqjdcwsensor sensor) {
            if (sensor != null) {
                if (sensor.getLasthisdatatime() == null) {
                    add(sensor);
                    return new Date();
                } else {
                    long lasttime = 0;
                    long nowtime = 0;
                    try {
                        lasttime = HexUtil.todate(sensor.getLasthisdatatime()).getTime();
                        nowtime = HexUtil.todate(new Date()).getTime();
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                    int timersp = 60000;
                    if (sensor.getLastalarmlevel() != 0) {
                        timersp = ad.getHisalarmtimersp()*1000;
                    } else {
                        timersp = ad.getHistimersp()*1000;
                    }
                    if (lasttime + timersp < nowtime) {
                        add(sensor);
                        return new Date();
                    }
                }
            }
            return null;
        }

        private void add(Dqjdcwsensor sensor) {
            Dqjdcwhistory his = new Dqjdcwhistory();
            his.setDeviceaddr(sensor.getDeviceaddr());
            his.setDevicegroup(sensor.getDevicegroup());
            his.setAlarmlevel(sensor.getLastalarmlevel());
            his.setAlarmmessage(sensor.getLastalarmmessage());
            his.setDatatime(sensor.getLastdatatime());
            his.setPointname(sensor.getPointname());
            his.setPointaddr(sensor.getPointaddr());
            his.setStationid(sensor.getStationid());
            //需要添加自己定义的属性
            his.setAtemper(sensor.getLastatemper());
            his.setBtemper(sensor.getLastbtemper());
            his.setCtemper(sensor.getLastctemper());
            his.setDtemper(sensor.getLastdtemper());
            his.setSbv(sensor.getLastv());
            his.setSbcount(sensor.getLastcount());
            dqjdcwsensorServiceImpl.Add(his);
        }


        @Async("threadPool")
        public void startSendThread(Appdevice Appdevice) throws Exception {
            checkType = "crc16";
           // setText("端口" + Appdevice.getCom() + "打开成功");
            issend.put(Thread.currentThread().getId(), true);
            String cstr = "";
            String cmdtype = "";
            String nametype = "";
            int timersp = (int) Math.round(Appdevice.getTimersp() * 1000);
            while (issend.get(Thread.currentThread().getId()) != null) {
                if (addrindex > Appdevice.getAddrmax() || addrindex < Appdevice.getAddrmin())
                    addrindex = Appdevice.getAddrmin();
                if (Pointcount < Appdevice.getPointcount())
                {
                  if (reSend[addrindex] == 0)
                    Pointcount ++;
                }
                else
                    Pointcount =1;

                try {
                    if(Appdevice.getBrand().equals("旧协议"))
                    {
                        cstr = String.format(Appdevice.getCmd(), String.format("%02X", addrindex));

                        //cstr = String.format(String.format("%02X030033%04X", addrindex,(Appdevice.getPointcount())*3));

                        cstr = cstr + CRC16.calcCrc16(cstr);
                        Send(cstr);
                    }
                    else
                    {
                        cstr = String.format(String.format("%02X03%04X000c", addrindex,0x0100 +(Pointcount-1)*12));
                        cstr = cstr + CRC16.calcCrc16(cstr);
                        Send(cstr);
                    }

                } catch (Exception EX) {
                     setText(EX.toString());
                }
                //setText("向" + Appdevice.getName() + "设备发送指令" + cstr);
                reSend[addrindex]++;
                if (reSend[addrindex] > 3) {
                dqjdcwsensorServiceImpl.UpdateStatus(ad, addrindex,1);
                reSend[addrindex] = 0;
                addrindex++;
                }
                Thread.sleep(timersp);
            }
        }

        // @Async("threadPool")
        // public void startReceiveThread(){
        //     isrecv.put(Thread.currentThread().getId(), true);
        //     while (isrecv.get(Thread.currentThread().getId()) != null) {
        //         //这里根据实际协议替换,解析方法recvCrc16;recvSum();
        //         recv();
        //         try {
        //             Thread.sleep(interval);
        //         } catch (InterruptedException e) {
        //             e.printStackTrace();
        //         }
        //     }
        // }
}
